#include "Restricoes.h"
#include <locale>

void Restricoes::calcular()
{
    #pragma omp single
    {
        for (int i = 0; i < numStatics; i++)
        {
            statics[i]->F[0] = 0.0;
            statics[i]->F[1] = 0.0;
            statics[i]->F[2] = 0.0;
        }
        for (int j = 0; j < numSockets ; j++)
        {
            sockets[j]->F[0] = 0.0;
            sockets[j]->F[1] = 0.0;
        }
    }
    //barreira implícita
}

void Restricoes::imprimeForcasEstaticas()
{
    for (int i = 0; i < numStatics; i++)
    {
        cout << "element " << i ;
        cout << statics[i]->F[0];
        cout << statics[i]->F[1];
        cout << statics[i]->F[2];
        cout << '\n';
    }
}

void Restricoes::imprimeForcasSockets()
{
    double forcaTotalEmY=0.0;
    for (int i = 0; i < numSockets; i++)
    {
       //cout << '\n' << sockets[i]->F[1];
        forcaTotalEmY += sockets[i]->F[1];
    }
    if (hitTime==0.0)
    {
        if(forcaTotalEmY>0.0)hitTime=sockets[0]->R[1];
    }
    else
    {
       fprintf( arqSaidaForcas,"%f\t%lf\n",(hitTime-sockets[0]->R[1]),forcaTotalEmY);
    }
    //fprintf( arqSaidaForcas,"\n%f;%lf",(20-sockets[0]->R[1]),forcaTotalEmY*1.0E-04);
    //printf ("\nPosY: %f F[y]: %lf",sockets[0]->R[1],forcaTotalEmY);
    //printf ("\nNovos");
}

Restricoes::Restricoes(MODEL*md)
{
    hitTime=0.0;
    char name [20];
    arqSaidaForcas = fopen ("saidaForcas1.txt","w");
    pModel=md;
    numSockets=numStatics=0;
    //Itero na lista de todas as esferas e conto cada elemento estático e socket
    for (SPHERE* s = pModel->SPHList.Begin; s != NULL; s = s->Next)
    {
        if (s->Constraint == SPHERE::STATIC) numStatics++;
        else if (s->Constraint == SPHERE::SOCKET) numSockets++;
    }
    cout << "Número de Sockets: " << numSockets << '\n';
    cout << "Número de Estáticos: " << numStatics << '\n';
    //Aloco espaço para eles nos dois vetores
    sockets=new SPHERE*[numSockets];
    statics=new SPHERE*[numStatics];
    int contSock=0;
    int contSta=0;
    //Com eles contados, posso inserí-los em seus respectivos vetores
    for (SPHERE* s = pModel->SPHList.Begin; s != NULL; s = s->Next)
    {
        if (s->Constraint == SPHERE::STATIC)
        {
            statics[contSta]=s;
            contSta++;
        }
        else if (s->Constraint == SPHERE::SOCKET)
        {
            sockets[contSock]=s;
            contSock++;
        }
    }
}

RestricoesParalelo::RestricoesParalelo(MODEL*md)
{
    hitTime=0.0;
    char name [20];
    arqSaidaForcas = fopen ("saidaForcas1.txt","w");

    pModel=md;
    numSockets=numStatics=0;
    //Itero na lista de todas as esferas e conto cada elemento estático e socket
    for (SPHERE* s = pModel->SPHList.Begin; s != NULL; s = s->Next)
    {
        if (s->Constraint == SPHERE::STATIC) numStatics++;
        else if (s->Constraint == SPHERE::SOCKET) numSockets++;
    }
    cout << "Número de Sockets: " << numSockets << '\n';
    cout << "Número de Estáticos: " << numStatics << '\n';
    //Aloco espaço para eles nos dois vetores
    sockets=new SPHERE*[numSockets];
    statics=new SPHERE*[numStatics];
    int contSock=0;
    int contSta=0;
    //Com eles contados, posso inserí-los em seus respectivos vetores
    for (SPHERE* s = pModel->SPHList.Begin; s != NULL; s = s->Next)
    {
        if (s->Constraint == SPHERE::STATIC)
        {
            statics[contSta]=s;
            contSta++;
        }
        else if (s->Constraint == SPHERE::SOCKET)
        {
            sockets[contSock]=s;
            contSock++;
        }
    }
}
void RestricoesParalelo::calcular()
{
    // A cada passo percorro a lista e zero a contribuição dos dois
    #pragma omp for nowait
    for (int i = 0; i < numStatics; i++)
    {
        statics[i]->F[0] = 0.0;
        statics[i]->F[1] = 0.0;
        statics[i]->F[2] = 0.0;
    }
    //sem barreira
    #pragma omp for
    for (int j = 0; j < numSockets ; j++)
    {
        sockets[j]->F[0] = 0.0;
        sockets[j]->F[1] = 0.0;
    }
    //barreira implícita
}
